﻿namespace JoinBox.WPF; // WPF的钩子

using System;
using System.Windows;
using System.Collections.ObjectModel;
using System.Windows.Controls.Primitives;
using KeyEventArgs = System.Windows.Input.KeyEventArgs;
using ListBox = System.Windows.Controls.ListBox;
using RadioButton = System.Windows.Controls.RadioButton;

using System.Windows.Interop;
using System.Diagnostics;
using System.Windows.Input;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;

/// <summary>
/// 钩子工具
/// </summary>
public class HookProcessing
{
    /// <summary>
    /// 处理按了X关闭的时候
    /// </summary>
    /// <param name="dependencyObject">窗口的指针,通常为this</param>
    /// <param name="func">委托,给它传回调函数</param>
    public static void PressCloseFork(DependencyObject dependencyObject, Action func)
    {
        int LOWORD(int n)
        {
            return n & 0xffff;
        }
        /// https://social.msdn.microsoft.com/Forums/en-US/549a4bbb-e77b-4c5a-b724-07996774c60a/closereason-on-wpf-window?forum=wpf
        IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            switch (msg)
            {
                case 0x11:
                case 0x16:
                    {
                        Debug.WriteLine("PressCloseFork输出: 关闭原因：窗口关闭");
                    }
                    break;
                case 0x112:// 点击了面板
                    {
                        if ((LOWORD((int)wParam) & 0xfff0) == 0xf060)// 按了x关闭
                        {
                            Debug.WriteLine("PressCloseFork输出: 关闭原因：用户关闭");
                            func?.Invoke();
                        }
                    }
                    break;
            }
            return IntPtr.Zero;
        }
        var source = (HwndSource)PresentationSource.FromDependencyObject(dependencyObject);
        source.AddHook(WindowProc);
    }
}


public static class WPFTool
{
    /// <summary>
    /// 获取文本框触发的回车
    /// </summary>
    /// <param name="e">传到的数据</param>
    /// <param name="text">路径或文件</param>
    /// <param name="listBox">把要路径或文件的内容列表写到这个ListBox</param>
    public static void GetEnterKey(KeyEventArgs e, string text, ObservableCollection<string> ocs)
    {
        if (e.Key == Key.Enter)
            SetFilesForControl(text, ocs);
    }

    /// <summary>
    /// 删除listbox所有内容
    /// </summary>
    /// <param name="listBox"></param>
    public static void DelItemAll(ListBox listBox)
    {
        while (listBox.Items.Count != 0)
            listBox.Items.RemoveAt(listBox.Items.Count - 1); // 删除选中项目
    }
    /// <summary>
    /// 判断string的是路径还是文件,将内容加入list
    /// </summary>
    /// <param name="path">词库文件夹</param>
    /// <param name="list">数据绑定的控件</param>
    public static void SetFilesForControl(string path, ObservableCollection<string> list)
    {
        var hashset = new HashSet<string>();
        if (Directory.Exists(path))
        {
            var dir = new DirectoryInfo(path);
            foreach (var f in dir.GetFiles())
                hashset.Add(f.FullName);
        }
        else if (File.Exists(path))
            hashset.Add(path);

        // 消重,并且加入数据绑定控件
        var xt = hashset.Except(list).Distinct();
        foreach (var item in xt)
            list.Add(item);
    }
    /// <summary>
    /// 删除listbox某几行内容,返回
    /// </summary>
    /// <param name="listBox"></param>
    /// <returns>哪几行被删除了</returns>
    public static int[] DelItem(this ListBox listBox)
    {
        var re = new List<int>();// 将所有选择的记录下来
        int selIndex = -1;
        // 如果listbox是多选的,循环删除
        while (listBox.SelectedIndex != -1)
        {
            selIndex = listBox.SelectedIndex; // 选中项目索引
            listBox.Items.RemoveAt(selIndex); // 不断删除选中的第一个
            re.Add(selIndex);
        }
        int itemCount = listBox.Items.Count;  // 项目数
        // 选中删除后的前一项
        if (itemCount > selIndex)
            listBox.SelectedIndex = selIndex;
        else
            listBox.SelectedIndex = selIndex - 1;
        return re.ToArray();
    }

    public class CRadioButton
    {
        /// <summary>
        /// 获取组内单选按钮,获取选中
        /// </summary>
        public CRadioButton(UniformGrid uf)
        {
            UniformGrid = uf ?? throw new ArgumentNullException(nameof(uf));
        }

        /// <summary>
        /// 控件组
        /// </summary>
        public UniformGrid UniformGrid;
        string? _name;
        public string? Name
        {
            get
            {
                if (_name == null)
                {
                    foreach (var rac in UniformGrid.Children)
                    {
                        if (rac is RadioButton ra &&
                            ra.IsChecked is not null &&
                            ra.IsChecked.Value)// 选中
                        {
                            _name = ra.Content.ToString();
                            if (!IsChineseAll(_name[0].ToString()))
                                _name = _name.Substring(1);
                            break;
                        }
                    }
                }
                return _name;
            }
            set
            {
                foreach (var rac in UniformGrid.Children)
                {
                    if (rac is not RadioButton ra)
                        continue;
                    _name = ra.Content.ToString();
                    if (!IsChineseAll(_name[0].ToString()))
                        _name = _name.Substring(1);

                    if (_name == value)
                    {
                        ra.IsChecked = true;
                        break;
                    }
                }
            }
        }

        /// <summary>
        /// 从头到尾是中文
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsChineseAll(string str)
        {
            return Regex.Match(str, @"^[\u4e00-\u9fa5]+$").Success;
        }
    }

    /// <summary>
    /// 先清空集合,再通过路径上文本设置到集合
    /// </summary>
    /// <param name="path">文本路径</param>
    /// <param name="textViw">文本视表</param>
    /// <param name="link">要更新的超链接路径</param>
    // public static void PathViwToTextViw(string path, ListBox textViw, ref string link)
    // {
    //    if (!string.IsNullOrEmpty(path) && File.Exists(path) && link != path)
    //    {
    //        // 清空listbox,再导入txt内容
    //        DelItemAll(textViw);
    //        var lines = BasalCurrency.FileHelper.ReadAllLines(path);
    //        foreach (var line in lines)
    //            textViw.Items.Add(line);

    //        link = path;
    //    }
    // }
}
